package com.otp.webapp.action;

import com.otp.model.test.instance.TestInstance;
import com.otp.model.test.template.ReportCriteria;
import com.otp.model.test.template.TestTemplate;
import com.otp.service.util.FormatScoreUtil;
import com.otp.webapp.action.BasePage;
import com.otp.model.test.instance.TestInstanceScore;
import com.otp.model.test.template.TestScoringAlgorithm;
import com.otp.model.test.template.ReportTemplate;

public class DisplayTestResult extends BasePage implements java.io.Serializable{

	private static final long serialVersionUID = 1L;
	
	//score strings available by getters:
	/*maxScoreString
	rawScoreString
	percentageScoreString
	zetaScoreString
	percentileRankString
	stenScoreString
	thetaEAPString
	thetaMLString
	thetaMAPString
	errorEAPString
	errorMLString
	errorMAPString*/

	private TestInstanceScore testInstanceScore;
	private TestTemplate testTemplate;
	private TestInstance testInstance;
	private ReportTemplate reportTemplate;
	private ReportCriteria reportCriteria;
	private TestScoringAlgorithm algorithm;


	public DisplayTestResult(TestInstanceScore testInstanceScore){
		testInstance = testInstanceScore.getTestInstance();
		testTemplate = testInstanceScore.getTestTemplate();
		reportTemplate = testTemplate.getReportTemplate();
		this.testInstanceScore = testInstanceScore;
		TestScoringAlgorithm algo = testInstanceScore.getTestAlgorithmTypes();
		if(algo!=null) algorithm=algo;
		else algorithm = testInstance.getTestScoringAlgorithm();
	}	

	/**
	 * Returns the reportCriteria field if it is empty based on the score
	 * Calculates the report criteria if it s not empty
	 * If empty initializes it with a dummy object
	 */
	private ReportCriteria getRelevantReportCriteria() {
		if (reportCriteria == null){
			// Find the right report criteria
			//System.out.println("All criteria="+getTestTemplate().getReportTemplate().getReportCriteria());
			if (getTestTemplate().getReportTemplate() == null) {
				reportCriteria = new ReportCriteria();
				reportCriteria.setLongDescription("No Report template available");
				reportCriteria.setShortDescription("No Report template available");			
			} else if (getTestTemplate().getReportTemplate().getReportCriteria() == null ||
					getTestTemplate().getReportTemplate().getReportCriteria().size() == 0) {
				reportCriteria = new ReportCriteria();
				reportCriteria.setLongDescription("No Report criteria found");
				reportCriteria.setShortDescription("No Report criteria found");			
			} else { // Try to match 
				for (ReportCriteria rc: getTestTemplate().getReportTemplate().getReportCriteria()){
					Double score=0.0;
					if(isByRawScore()) score=getRawScore();
					if(isByTheta()){
						if(getThetaEAP()!=null) score=getThetaEAP();
						else if (getThetaMAP()!=null) score=getThetaMAP();
						else if(getThetaML()!=null) score=getThetaML();
						else {addError("A theta value is required for adaptive tests"); return null;}
					}

					if (rc.getMin() <=score && rc.getMax() >= score){ // changed to min <= score <= max 
						reportCriteria=rc;
						break; // added to fix issue 43
					}
					// reportCriteria=rc; // removed to fix issue 43
				}
				//if nothing found create a dummy object
				if (reportCriteria == null) {
					reportCriteria = new ReportCriteria();
					reportCriteria.setLongDescription("Report criteria could not be mapped");
					reportCriteria.setShortDescription("Report criteria could not be mapped");
				}
			}
			if (reportCriteria == null) {
				reportCriteria = new ReportCriteria();
				reportCriteria.setLongDescription("Report criteria unknown");
				reportCriteria.setShortDescription("Report criteria unknown");
			}
		}
		return reportCriteria;
	}

	public String getScoreShortDescription() {//TODO not efficient. Relevant criteria are determined twice
		return getRelevantReportCriteria().getShortDescription();
	}
	public String getScoreLongDescription() {
		return getRelevantReportCriteria().getLongDescription();
	}
	public String getReportLongDescription() {
		return getTestTemplate().getReportTemplate().getLongDescription();
	}
	public TestTemplate getTestTemplate() {
		return testTemplate;
	}
	public void setTestTemplate(TestTemplate testTemplate) {
		this.testTemplate = testTemplate;
	}
	public TestInstance getTestInstance() {
		return testInstance;
	}
	public void setTestInstance(TestInstance testInstance) {
		this.testInstance = testInstance;
	}
	public ReportTemplate getReportTemplate() {
		return reportTemplate;
	}
	public void setReportTemplate(ReportTemplate reportTemplate) {
		this.reportTemplate = reportTemplate;
	}

	public TestInstanceScore getTestInstanceScore(){
		return testInstanceScore;
	}
	public void setTestInstanceScore(TestInstanceScore testInstanceScore){
		this.testInstanceScore = testInstanceScore;
	}

	public Double getMaxScore() {
		return testInstanceScore.getMaxScore();
	}

	public Double getRawScore() {
		return testInstanceScore.getRawScore();
	}

	public Double getPercentageScore() {
		return testInstanceScore.getPercentageScore();
	}

	public Double getZetaScore() {
		return testInstanceScore.getZetaScore();
	}

	public Double getPercentileRank() {
		return testInstanceScore.getPercentileRank();
	}

	public Double getStenScore() {
		return testInstanceScore.getStenScore();
	}

	public Double getThetaEAP() {
		return testInstanceScore.getThetaEAP();
	}

	public Double getThetaML() {
		return testInstanceScore.getThetaML();
	}

	public Double getThetaMAP() {
		return testInstanceScore.getThetaMAP();
	}

	public Double getErrorEAP() {
		return testInstanceScore.getErrorEAP();
	}

	public Double getErrorML() {
		return testInstanceScore.getErrorML();
	}


	public Double getErrorMAP() {
		return testInstanceScore.getErrorMAP();
	}

	public String getMaxScoreString(){
		Double score = getMaxScore();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 1);
	}

	public String getRawScoreString(){
		Double score = getRawScore();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 1);
	}

	public String getPercentageScoreString(){
		Double score = getPercentageScore();
		if(score==null) return "null";
		if(score<0.001) return FormatScoreUtil.formatScoresPerCent(score, 2); 
		return FormatScoreUtil.formatScoresPerCent(score, 1);
	}

	public String getZetaScoreString(){
		Double score = getZetaScore();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 1);
	}

	public String getPercentileRankString(){
		Double score = getPercentileRank();
		if(score==null) return "null";
		if(score<0.001) return FormatScoreUtil.formatScoresPerCent(score,2);
		return FormatScoreUtil.formatScoresPerCent(score, 1);
	}

	public String getStenScoreString(){
		Double score = getStenScore();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 0);
	}

	public String getThetaEAPString(){
		Double score = getThetaEAP();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 7);
	}

	public String getThetaMAPString(){
		Double score = getThetaMAP();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 7);
	}	

	public String getThetaMLString(){
		Double score = getThetaML();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 7);
	}	

	public String getErrorEAPString(){
		Double score = getErrorEAP();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 2);
	}

	public String getErrorMAPString(){
		Double score = getErrorMAP();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 2);
	}

	public String getErrorMLString(){
		Double score = getErrorML();
		if(score==null) return "null";
		return FormatScoreUtil.formatScores(score, 2);
	}

	public String getTestName() {
		return getTestTemplate().getName();
	}

	public boolean isByRawScore() {
		String algorithm = this.algorithm.getAlgorithm();
		if(algorithm.equals("STANDARD_NON_ADAPTIVE")
				||algorithm.equals("RANDOM"))
			return true;
		return false;
	}

	public boolean isByTheta() {
		String algorithm = this.algorithm.getAlgorithm();
		if(algorithm.equals("ADAPTIVE_DICHOTOMOUS")
				||algorithm.equals("ADAPTIVE_POLYTOMOUS")
				||algorithm.equals("ADAPTIVE_DICHOTOMOUS_MULT_ITEMS")
				||algorithm.equals("ADAPTIVE_POLYTOMOUS_MULT_ITEMS")
				||algorithm.equals("STATIC_DICHOTOMOUS")
				||algorithm.equals("STATIC_POLYTOMOUS")
				)
			return true;
		return false;
	}

}
